# [二] Spring 程序入口和xml解析
# [1] Spring 源码下载
1、git clone --branch v5.1.3.RELEASE https://gitee.com/Z201/spring-framework.git。
2、gradle 下载,gradle 要 JDK8 的版本。
3、到下载的 spring 源码路径执行 gradle 命令。
gradlew :spring-oxm:compileTestJava
4、用 idea 打开 spring 源码工程,在 idea 中安装插件 kotlin,重启 idea 5、把编译好的源码导入到工程中。
# [2] 把源码导入到工程
# [3] 导入 jar 依赖
Spring 中最核心的 4 个 jar
- Spring-beans
- Spring-core
- Spring-context
- Spring-expression
一个最最简单的 spring 工程,理论上就只需要一个 jar 就够了
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
Spring-context 包本身就依赖了,Spring-aop,Spring-beans,Spring-core 包
一个空的 spring 工程是不能打印日志的,要导入 spring 依赖的日志 jar
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>LATEST</version>
</dependency>
# [4] Spring 容器加载方式
- 1、类路径获取配置文件
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring.xml");
- 2、文件系统路径获取配置文件[绝对路径]
ApplicationContext applicationContext = new
FileSystemXmlApplicationContext("E:\\idea\\springdemo\\spring.xml");
- 3 、 无 配 置 文 件 加 载 容 器
ApplicationContext applicationContext = new
AnnotationConfigApplicationContext("com.xx.jack");
- 4、springboot 加载容器
ApplicationContext applicationContext = new EmbeddedWebApplicationContext();
# [5] Spring 容器加载核心方法
AbstractApplicationContext.refresh()
方法
refresh()方法是 spring 容器启动过程中的核心方法,spring 容器要加载必须执行该方法。
# [6] Xml 流程分析
# [7] 自定义标签解析
- 1、获取自定义标签的 namespace 命令空间,例如:
http://www.springframework.org/schema/context
String namespaceUri = getNamespaceURI(ele);
- 2、根据命令空间获取 NamespaceHandler 对象。
NamespaceUri 和NamespaceHandler 之间会建立一个映射,spring 会从所有的spring jar 包中扫描 spring.handlers 文件,建立映射关系。
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve( namespaceUri);
Map<String, Object> handlerMappings = getHandlerMappings();
Object handlerOrClassName = handlerMappings.get(namespaceUri);
- 3、反射获取 NamespaceHandler 实例
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
- 4、调用 init 方法
namespaceHandler.init();
- 5、调用 parse 方法
handler.parse(ele, new ParserContext(this.readerContext,
this, containingBd))
扩展
spring.handler文件其实就是 namespaceUri 和类的完整限定名的映射。